import os
import glob
from scripts.llm_client import call_glm

# --- 配置区 ---
# 定义源目录和目标目录，方便未来修改
APP_NAME = 'poll'  # TODO 这个应该作为参数传入.
FEATURES_DIR = os.path.join(APP_NAME, 'tests', 'features')
STEPS_DIR = os.path.join(APP_NAME, 'tests', 'steps')
MODELS_FILE = os.path.join(APP_NAME, 'models.py')
# --- 结束配置 ---


def generate_and_write_steps(feature_file_path: str):
    """
    读取一个 .feature 文件，调用 LLM 生成 BDD Steps，并将其写入对应的 .py 文件。
    """
    try:
        # 1. 智能计算输出路径
        base_name = os.path.basename(feature_file_path)  # e.g., "voting.feature"
        name_without_ext = os.path.splitext(base_name)[0] # e.g., "voting"
        output_filename = f"test_{name_without_ext}.py"    # e.g., "test_voting.py"
        output_filepath = os.path.join(STEPS_DIR, output_filename)

        print(f"[*] 正在处理: {feature_file_path}")

        # 2. 读取上下文文件
        with open(feature_file_path, 'r', encoding='utf-8') as f:
            feature_content = f.read()

        with open(MODELS_FILE, 'r', encoding='utf-8') as f:
            models_content = f.read()

        # 3. 构建 Prompt 并调用 LLM
        prompt = f"""
        你是一个资深的Django开发专家，精通pytest-bdd测试框架。
        基于以下的 Gherkin feature 文件和 Django models.py 文件，为我生成完整的 pytest-bdd step definition python 代码。

        请确保：
        1. 导入所有必要的库，包括 `pytest` 并使用 `@pytest.mark.django_db` 模块级标记来启用数据库访问。
        2. 使用 `from pytest_bdd import scenarios, given, when, then, parsers`。
        3. 正确导入 `{APP_NAME}.models` 中的模型。
        4. 对 Gherkin 语句中的变量使用 `parsers.parse()`。
        5. 在测试函数中编写正确的 Django ORM 操作逻辑。
        6. 返回纯粹的、可以直接运行的 Python 代码，不包含任何解释或 markdown 标记。

        --- Gherkin Feature File Content ---
        {feature_content}

        --- Django models.py Content ---
        {models_content}

        --- Generated Python Code ---
        """

        print("    -> 正在调用 LLM 生成代码...")
        generated_code = call_glm(prompt)

        # 检查LLM是否返回了错误信息
        if generated_code.startswith("Error"):
             print(f"    [!] LLM 调用失败: {generated_code}")
             return

        # 4. 确保目标目录存在并写入文件
        os.makedirs(STEPS_DIR, exist_ok=True)
        with open(output_filepath, 'w', encoding='utf-8') as f:
            f.write(generated_code)

        print(f"    -> [成功] 已将代码写入: {output_filepath}")

    except FileNotFoundError as e:
        print(f"[!] 错误：找不到文件 {e.filename}。请检查路径是否正确。")
    except Exception as e:
        print(f"[!] 处理 {feature_file_path} 时发生未知错误: {e}")


def main():
    """
    主函数，自动发现所有 feature 文件并为它们生成 step definitions。
    """
    print("--- 开始自动生成 BDD Step Definitions ---")
    
    # 自动查找所有 .feature 文件
    feature_files = glob.glob(os.path.join(FEATURES_DIR, '*.feature'))

    if not feature_files:
        print(f"[!] 在 '{FEATURES_DIR}' 目录下没有找到任何 .feature 文件。")
        return

    for file_path in feature_files:
        generate_and_write_steps(file_path)
        print("-" * 40)

    print("--- 所有任务已完成 ---")


if __name__ == "__main__":
    # 使用 -m 方式运行时，需要确保项目根目录在 sys.path 中
    import sys
    # 这是一个简单的检查，确保脚本可以从根目录被模块化运行
    if 'scripts' not in sys.modules:
        project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        if project_root not in sys.path:
            sys.path.insert(0, project_root)
            
    main()